默认参数

  一个通用函数所需要的参数常常比处理简单情况时所需要的参数更多一些。特别地,那些为对象构造所用的函数(10.2.3节)通常都为灵活性而提供了一些选项。考虑一个打印整数的函数,给用户一个关于以什么为基数去打印它的选项是很合理的,但是在大部分程序里,整数都会按十进制的形式打印。例如,

    void print(int value, int base = 10);            // 默认的base是10

    void f()
    {
        print(31);
        print(31, 10);
        print(31, 16);
        print(31, 2);
    }

可能产生

31    31    1f    11111

也可以通过重载得到这种默认参数的效果

    void print(int value, int base);
    inline void print(int value) { print(value, 10); }

当然,采用重载将使读者不容易看到原来的意图:用一个函数加上一种简写形式。

  默认参数的类型将在函数声明时检查,在调用时求值。只可能对排列在最后的那些参数提供默认参数,例如,

    int f(int, int = 0, char* = 0);        // ok
    int g(int = 0, int = 0, char*);        // 错误❌
    int g(int = 0, int, char* = 0);        // 错误❌

请注意,在 * 和 = 之间的空格是重要的(*= 是一个赋值运算符,6.2节)。

int nasty(char*=0);                    // 语法错❌

在同一个作用域中随后的声明里,默认参数都不能重复或者改变。例如,

    void f(int x = 7);
    void f(int = 7);                        // 错误❌:默认参数不能重复
    void f(int = 8);                        // 错误❌:默认参数不能改变

    void g()
    {
        void f(int x = 9);                  // 可以✅:这个声明将屏蔽外层的声明
        // ...
    }

在嵌套作用域里声明一个名字,让它去屏蔽在外层作用域里同一名字的声明,这种做法很容易引出错误。

🔚